#ifndef xpack_utils_bexx
#define xpack_utils_bexx
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::utils_bexx::inc
#include"define/base_type.hpp"
#include"macro/xexport.hpp"
#include"meta/unsigned_type.hpp"
#include"meta/is_signed.hpp"
#pragma pop_macro("xuser")

namespace mixc::utils_bexx::origin{
    template<class type_t, uxx bytes_v = sizeof(type_t)>
    requires(0 < bytes_v and bytes_v <= sizeof(u64))
    struct bexx{
    private:
        u08 items[bytes_v];
    public:
        bexx() : items{} {}
        bexx(type_t value) : 
            items{} {
            for(uxx i = 0; i < bytes_v; i++){
                auto get_byte       = u08(inc::unsigned_type<type_t>(value) >> (i * xbitsof(u08)));
                items[bytes_v - i - 1] = get_byte;
            }
        }

        operator type_t() const {
            type_t result = inc::is_signed<type_t> and (items[0] & 0x80) ? type_t(-1) << (bytes_v * xbitsof(u08)) : 0;

            for(uxx i = 0; i < bytes_v; i++){
                result |= type_t(items[bytes_v - i - 1]) << (i * xbitsof(u08));
            }
            return result;
        }
    };

    using beu16         = bexx<uxx, 2>;
    using bei16         = bexx<ixx, 2>;
    using beu24         = bexx<uxx, 3>;
    using bei24         = bexx<ixx, 3>;
    using beu32         = bexx<uxx, 4>;
    using bei32         = bexx<ixx, 4>;
    using beu40         = bexx<u64, 5>;
    using bei40         = bexx<i64, 5>;
    using beu48         = bexx<u64, 6>;
    using bei48         = bexx<i64, 6>;
    using beu56         = bexx<u64, 7>;
    using bei56         = bexx<i64, 7>;
    using beu64         = bexx<u64, 8>;
    using bei64         = bexx<i64, 8>;
}

#endif

xexport_space(mixc::utils_bexx::origin)
